#include "handleobj.h"
#include "qpushbutton.h"

HandleObj::HandleObj(QWidget *parent)
    : QWidget{parent}
{}


// 按键事件设置：鼠标悬停时放大，离开时缩小，按下时缩小，松开时放大
bool HandleObj::handleButtonEvent(QPushButton *button, QEvent *event)
{
    if(event->type() == QEvent::HoverEnter)
    {
        button->setIconSize(button->size());

        return true;
    }
    else if(event->type() == QEvent::HoverLeave)
    {
        button->setIconSize(button->size() - QSize(picSize, picSize));

        return true;
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        button->setIconSize(button->size() - QSize(picSize, picSize));

        return true;
    }
    else if(event->type() == QEvent::MouseButtonRelease)
    {
        button->setIconSize(button->size());

        return true;
    }

    return true;
}


// 按键样式设置：添加图片样式
void HandleObj::handleButtonStyle(QPushButton *button, QString pic, QObject *obj)
{
    QIcon Icon;
    Icon.addFile(assetsPath + pic);
    button->setStyleSheet( "QPushButton { background-color:transparent; }" );
    button->setText("");
    button->setIcon(Icon);
    button->setIconSize(button->size() - QSize(picSize, picSize));
    button->installEventFilter(obj);
}


// 开关事件设置：鼠标悬停时放大，离开时缩小，按下时缩小，松开时放大并切换图片
bool HandleObj::handleSwitchEvent(QPushButton *button, QEvent *event, QString pic1, QString pic2)
{
    QIcon Icon;
    static bool switchState = 0;

    if(event->type() == QEvent::HoverEnter)
    {
        button->setIconSize(button->size());

        return true;
    }
    else if(event->type() == QEvent::HoverLeave)
    {
        button->setIconSize(button->size() - QSize(picSize, picSize));

        return true;
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        button->setIconSize(button->size() - QSize(picSize, picSize));

        return true;
    }
    else if(event->type() == QEvent::MouseButtonRelease)
    {
        button->setIconSize(button->size());

        switchState = !switchState;

        if(switchState)
        {
            Icon.addFile(assetsPath + pic1);
            button->setIcon(Icon);
        }
        else
        {
            Icon.addFile(assetsPath + pic2);
            button->setIcon(Icon);
        }

        return true;
    }

    return true;
}

// 开关样式设置：添加图片样式
void HandleObj::handleSwitchStyle(QPushButton *button, QString pic, QObject *obj)
{
    handleButtonStyle(button, pic, obj);
}

// 自定义按键事件设置：鼠标悬停时放大，离开时缩小，按下时缩小，松开时放大并切换图片，自定义样式
bool HandleObj::handleUserButtonEvent(QPushButton *button, QEvent *event, QString style1, QString style2, QString style3)
{
    QIcon Icon;
    int height = button->height();
    int width = button->width();

    if(event->type() == QEvent::HoverEnter)
    {
        button->resize(height+objSize, width+objSize);
        button->setIconSize(button->size() / 2);
        button->setStyleSheet(style2);

        return true;
    }
    else if(event->type() == QEvent::HoverLeave)
    {
        button->resize(height-objSize, width-objSize);
        button->setIconSize(button->size() / 2);
        button->setStyleSheet(style1);

        return true;
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        button->resize(height-objSize, width-objSize);
        button->setIconSize(button->size() / 2);
        button->setStyleSheet(style3);

        return true;
    }
    else if(event->type() == QEvent::MouseButtonRelease)
    {
        button->resize(height+objSize, width+objSize);
        button->setIconSize(button->size() / 2);
        button->setStyleSheet(style2);

        return true;
    }

    return true;
}


// 自定义按键事件设置：鼠标悬停时放大，离开时缩小，按下时缩小，松开时放大并切换图片，自定义样式
bool HandleObj::handleTipButtonEvent(QPushButton *button, QEvent *event, QString tip)
{
    if(event->type() == QEvent::HoverEnter)
    {
        QToolTip::showText(QCursor::pos(), tip, button);

        return true;
    }
}


// 自定义按键：自定义样式
void HandleObj::handleUserButtonStyle(QPushButton *button, QString pic, QString style, QObject *obj)
{
    QIcon Icon;
    Icon.addFile(assetsPath + pic);
    button->setStyleSheet(style);
    button->setText("");
    button->setIcon(Icon);
    button->setIconSize(button->size()/2);
    button->installEventFilter(obj);
}

void HandleObj::region(const QPoint &currentGlobalPoint)
{
    // 获取窗体在屏幕上的位置区域，topLeft为坐上角点，rightButton为右下角点
    QRect rect = this->rect();

    QPoint topLeft = this->mapToGlobal(rect.topLeft()); //将左上角的(0,0)转化为全局坐标
    QPoint rightButton = this->mapToGlobal(rect.bottomRight());

    int x = currentGlobalPoint.x(); //当前鼠标的坐标
    int y = currentGlobalPoint.y();

    if(((topLeft.x() + PADDING >= x) && (topLeft.x() <= x))
        && ((topLeft.y() + PADDING >= y) && (topLeft.y() <= y)))
    {
        // 左上角
        dir = LEFTTOP;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));  // 设置光标形状
    }else if(((x >= rightButton.x() - PADDING) && (x <= rightButton.x()))
               && ((y >= rightButton.y() - PADDING) && (y <= rightButton.y())))
    {
        // 右下角
        dir = RIGHTBOTTOM;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    }else if(((x <= topLeft.x() + PADDING) && (x >= topLeft.x()))
               && ((y >= rightButton.y() - PADDING) && (y <= rightButton.y())))
    {
        //左下角
        dir = LEFTBOTTOM;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    }else if(((x <= rightButton.x()) && (x >= rightButton.x() - PADDING))
               && ((y >= topLeft.y()) && (y <= topLeft.y() + PADDING)))
    {
        // 右上角
        dir = RIGHTTOP;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    }else if((x <= topLeft.x() + PADDING) && (x >= topLeft.x()))
    {
        // 左边
        dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }else if((x <= rightButton.x()) && (x >= rightButton.x() - PADDING))
    {
        // 右边
        dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }else if((y >= topLeft.y()) && (y <= topLeft.y() + PADDING))
    {
        // 上边
        dir = UP;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }else if((y <= rightButton.y()) && (y >= rightButton.y() - PADDING))
    {
        // 下边
        dir = DOWN;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }else
    {
        // 默认
        dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
}


//三个鼠标事件的重写
//鼠标按下事件
void HandleObj::mousePressEvent(QMouseEvent *event)
{
    switch(event->button())
    {
    case Qt::LeftButton:
        isLeftPressDown = true;

        if(dir != NONE)
        {
            this->mouseGrabber(); //返回当前抓取鼠标输入的窗口
        }
        else
        {
            m_movePoint = event->globalPos() - this->frameGeometry().topLeft();
            //globalPos()鼠标位置，topLeft()窗口左上角的位置
        }
        break;
    case Qt::RightButton:
        this->setWindowState(Qt::WindowMinimized);
        break;
    default:
        HandleObj::mousePressEvent(event);
    }
}



//鼠标移动事件
void HandleObj::mouseMoveEvent(QMouseEvent *event)
{
    QPoint globalPoint = event->globalPos();   //鼠标全局坐标

    QRect rect = this->rect();  //rect == QRect(0,0 1280x720)
    QPoint topLeft = mapToGlobal(rect.topLeft());
    QPoint bottomRight = mapToGlobal(rect.bottomRight());

    if (this->windowState() != Qt::WindowMaximized)
    {
        if(!isLeftPressDown)  //没有按下左键时
        {
            this->region(globalPoint); //窗口大小的改变——判断鼠标位置，改变光标形状
        }
        else
        {
            if(dir != NONE)
            {
                QRect newRect(topLeft, bottomRight); //定义一个矩形  拖动后最大1000*1618

                switch(dir)
                {
                case LEFT:

                    if(bottomRight.x() - globalPoint.x() <= this->minimumWidth())
                    {
                        newRect.setLeft(topLeft.x());  //小于界面的最小宽度时，设置为左上角横坐标为窗口x
                        //只改变左边界
                    }
                    else
                    {
                        newRect.setLeft(globalPoint.x());
                    }
                    break;
                case RIGHT:
                    newRect.setWidth(globalPoint.x() - topLeft.x());  //只能改变右边界
                    break;
                case UP:
                    if(bottomRight.y() - globalPoint.y() <= this->minimumHeight())
                    {
                        newRect.setY(topLeft.y());
                    }
                    else
                    {
                        newRect.setY(globalPoint.y());
                    }
                    break;
                case DOWN:
                    newRect.setHeight(globalPoint.y() - topLeft.y());
                    break;
                case LEFTTOP:
                    if(bottomRight.x() - globalPoint.x() <= this->minimumWidth())
                    {
                        newRect.setX(topLeft.x());
                    }
                    else
                    {
                        newRect.setX(globalPoint.x());
                    }

                    if(bottomRight.y() - globalPoint.y() <= this->minimumHeight())
                    {
                        newRect.setY(topLeft.y());
                    }
                    else
                    {
                        newRect.setY(globalPoint.y());
                    }
                    break;
                case RIGHTTOP:
                    if (globalPoint.x() - topLeft.x() >= this->minimumWidth())
                    {
                        newRect.setWidth(globalPoint.x() - topLeft.x());
                    }
                    else
                    {
                        newRect.setWidth(bottomRight.x() - topLeft.x());
                    }
                    if (bottomRight.y() - globalPoint.y() >= this->minimumHeight())
                    {
                        newRect.setY(globalPoint.y());
                    }
                    else
                    {
                        newRect.setY(topLeft.y());
                    }
                    break;
                case LEFTBOTTOM:
                    if (bottomRight.x() - globalPoint.x() >= this->minimumWidth())
                    {
                        newRect.setX(globalPoint.x());
                    }
                    else
                    {
                        newRect.setX(topLeft.x());
                    }
                    if (globalPoint.y() - topLeft.y() >= this->minimumHeight())
                    {
                        newRect.setHeight(globalPoint.y() - topLeft.y());
                    }
                    else
                    {
                        newRect.setHeight(bottomRight.y() - topLeft.y());
                    }
                    break;
                case RIGHTBOTTOM:
                    newRect.setWidth(globalPoint.x() - topLeft.x());
                    newRect.setHeight(globalPoint.y() - topLeft.y());
                    break;
                default:
                    break;
                }
                this->setGeometry(newRect);
            }
            else
            {
                move(event->globalPos() - m_movePoint); //移动窗口
                event->accept();
            }
        }
    }
}


//鼠标释放事件
void HandleObj::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isLeftPressDown = false;
        if (dir != NONE)
        {
            this->releaseMouse();
            this->setCursor(QCursor(Qt::ArrowCursor));
            dir = NONE;
        }
    }
}


QString HandleObj::truncateString(const QString &str, int maxLength)
{
    if (str.length() > maxLength) {
        return str.left(maxLength) + "..."; // 省略
    }
    return str;
}

bool HandleObj::isValidString(const QString &str)
{
    // 检查是否为空
    if (str.isEmpty())
        return false;

    // 正则表达式检查字符是否为有效的可打印字符
    QRegularExpression re("^[\\x20-\\x7E\\u4E00-\\u9FA5]+$"); // ASCII 和常用中文字符范围
    return re.match(str).hasMatch();
}

void HandleObj::listwidgetSetFont(QListWidget *list, int item_num, int font_size)
{
    QFont font = list->item(item_num)->font();
    font.setPointSize(font_size); // 设置选中项的字体大小
    list->item(item_num)->setFont(font);
}

QString HandleObj::generateToken(const QString &password, const QString &salt)
{
    QString tokenInput = password + salt;
    QByteArray tokenHash = QCryptographicHash::hash(tokenInput.toUtf8(), QCryptographicHash::Md5);
    return QString(tokenHash.toHex());
}
